package com.haikesi.api.mode.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.haikesi.api.base.Constants;
import com.haikesi.api.base.R;
import com.haikesi.api.base.Type;
import com.haikesi.api.mode.dao.ModeDao;
import com.haikesi.api.mode.dao.ModeDeviceDao;
import com.haikesi.api.mode.dao.PlatformModeDao;
import com.haikesi.api.mode.domain.po.ModeDevicePO;
import com.haikesi.api.mode.domain.po.ModePO;
import com.haikesi.api.mode.domain.po.PlatformModePO;
import com.haikesi.api.mode.domain.vo.*;
import com.haikesi.api.mode.service.IModeService;
import com.haikesi.exception.BusinessException;
import com.haikesi.util.ApcosApiUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import tk.mybatis.mapper.entity.Example;

import java.util.*;


@Service
@Transactional
public class ModeServiceImpl implements IModeService {

    @Autowired
    ModeDao modeDao;

    @Autowired
    ModeDeviceDao modeDeviceDao;

    @Autowired
    PlatformModeDao platformModeDao;

    private static Log log = LogFactory.getLog(ModeServiceImpl.class);

    @Override
    public List<ModeVO> getList(ModeSearchVO searchVO) {
        ModePO po = new ModePO();
        if (po.getUser() == null) {
            searchVO.setOrganizationId("");
            return modeDao.getList(searchVO);
        }
        searchVO.setOrganizationId(po.getUser().getOrganizationId());
        if (po.getUser().getIsAdmin() == 1) {
            searchVO.setOrganizationId("");
        }
        return modeDao.getList(searchVO);
    }

    @Override
    public List<ModeVO> listByAccount(String account) {
        //本地模式数据
        ModeSearchVO searchVO = new ModeSearchVO();
        searchVO.setPageNum(1);
        searchVO.setPageSize(100);
//        List<ModeVO> ModeVOList = getList(searchVO);
        List<ModeVO> ModeVOList = modeDao.listByAccount(account);
        Boolean flag = true;
        List<ModeVO> ModeVOList1 = new ArrayList<>();
        for (ModeVO vo : ModeVOList) {
            List<ModeDeviceVO> deviceList = getDeviceList(vo.getId());
            for(ModeDeviceVO modeDeviceVO : deviceList){
                if(!modeDeviceVO.getDeviceSubscriberNumber().equals(account)){
                    flag = false;
                }
            }
            if(flag){
                ModeVOList1.add(vo);
            }
        }
        return ModeVOList1;
    }

    @Override
    public R add(ModeAddVO modeAddVO) {
        ModePO po = new ModePO();
        BeanUtils.copyProperties(modeAddVO, po);
        po.setEnableMode(1);
        if (po.getUser() != null) {
            po.setOrganizationId(po.getUser().getOrganizationId());
        }
        po.preInsert();
        int i = modeDao.insertSelective(po);
        if (i == Constants.SQL_RETUN_SUCCESS) {
            throw new BusinessException(Type.EXCEPTION_FAIL);
        }
        return  new R().setData(po.getId());
    }

    @Override
    public void update(ModeUpdateVO updateVO) {
        ModePO po = new ModePO();
        BeanUtils.copyProperties(updateVO, po);
        if (po.getUser() != null) {
            po.setOrganizationId(po.getUser().getOrganizationId());
        }
        po.preUpdate();
        int i = modeDao.updateByPrimaryKeySelective(po);
        if (i == Constants.SQL_RETUN_SUCCESS) {
            throw new BusinessException(Type.EXCEPTION_FAIL);
        }
        //处理平台模式数据
        Example example = new Example(PlatformModePO.class);
        example.and().andEqualTo("modeId", updateVO.getId()).andEqualTo("delFlag", 0);
        List<PlatformModePO> list = platformModeDao.selectByExample(example);
        if (list == null || list.size() < 1) {
            return;
        }
        for (PlatformModePO platformModePO : list) {
            String platformModeId = platformModePO.getId();
            //更新本地数据
            BeanUtils.copyProperties(updateVO, platformModePO);
            platformModePO.preUpdate();
            platformModePO.setId(platformModeId);
            platformModeDao.updateByPrimaryKeySelective(platformModePO);
            //更新平台模式
            ModeApcosSetVO modeApcosSetVO = new ModeApcosSetVO();
            modeApcosSetVO.setId(platformModePO.getPlatformModeId());
            modeApcosSetVO.setMode_name(platformModePO.getModeName());
            modeApcosSetVO.setMode_readme(platformModePO.getModeReadme());
            modeApcosSetVO.setEnable_mode(platformModePO.getEnableMode() == 1 ? "yes" : "no");
            modeApcosSetVO.setMode_exe_after_say(platformModePO.getModeExeAfterSay());
            modeApcosSetVO.setMode_exe_before_say(platformModePO.getModeExeBeforeSay());
            modeApcosSetVO.setMode_exe_say_sound(platformModePO.getModeExeSaySound());
            modeApcosSetVO.setMode_exe_say_speed(platformModePO.getModeExeSaySpeed());
            modeApcosSetVO.setMode_exe_say_voice(platformModePO.getModeExeSayVoice());
            ApcosApiUtils.updateMode(platformModePO.getAccount(), modeApcosSetVO, platformModePO.getCmds());
        }

    }

    @Override
    public void delete(String id) {
        ModePO po = new ModePO();
        po.setId(id);
        po.preDelete();
        int i = modeDao.updateByPrimaryKeySelective(po);
        if (i == Constants.SQL_RETUN_SUCCESS) {
            throw new BusinessException(Type.EXCEPTION_FAIL);
        }

        //处理平台模式数据
        Example example = new Example(PlatformModePO.class);
        example.and().andEqualTo("modeId", id).andEqualTo("delFlag", 0);
        List<PlatformModePO> list = platformModeDao.selectByExample(example);
        if (list == null || list.size() < 1) {
            return;
        }
        for (PlatformModePO platformModePO : list) {
            //更新本地数据
            platformModePO.preDelete();
            platformModeDao.updateByPrimaryKey(platformModePO);
            //更新平台模式
            ModeApcosOpVO modeApcosOpVO = new ModeApcosOpVO();
            modeApcosOpVO.setId(platformModePO.getPlatformModeId());
            ApcosApiUtils.deletMode(platformModePO.getAccount(), modeApcosOpVO);
        }

    }

    @Override
    public List<ModeDeviceVO> getDeviceList(String modeId) {
        return modeDeviceDao.getDeviceList(modeId);
    }

    @Override
    public void controlMode(String id) {
        Example example = new Example(PlatformModePO.class);
        example.and().andEqualTo("modeId", id).andEqualTo("delFlag", 0);
        List<PlatformModePO> list = platformModeDao.selectByExample(example);
        log.info(">>>>>>>>>>"+list);
        if (list == null || list.size() < 1) {
            return;
        }
        for (PlatformModePO platformModePO : list) {
            ModeApcosOpVO modeApcosOpVO = new ModeApcosOpVO();
            modeApcosOpVO.setId(platformModePO.getPlatformModeId());
            ApcosApiUtils.sendMode(platformModePO.getAccount(), modeApcosOpVO);
        }
    }

    @Override
    public void setMode(ModeSetVO modeSetVO) {
        log.info("===========设置模式控制开始===========");
        ModePO modePO = modeDao.selectByPrimaryKey(modeSetVO.getId());//模型

        //设备控制数据
       // List<ModeDeviceVO> oldDeviceList = modeDeviceDao.getDeviceList(modeSetVO.getId());//查询原来的设备控制
        List<ModeDeviceVO> newdeviceList = modeSetVO.getDeviceList();


        //对比之前的数据整理出需要处理的数据
        HashMap<String, HashMap<String, List<ModeDeviceVO>>> addMap = new HashMap<>();
        HashMap<String, HashMap<String, List<ModeDeviceVO>>> updateMap = new HashMap<>();

        HashMap<String, Object> newMap = new HashMap<>();
        for (ModeDeviceVO vo : newdeviceList) {
            HashMap<String, List<ModeDeviceVO>> map = new HashMap<>();
            if (addMap.containsKey(vo.getDeviceSubscriberNumber())) {
                map = addMap.get(vo.getDeviceSubscriberNumber());
            }
            List<ModeDeviceVO> list = new ArrayList<>();
            if (map.containsKey(vo.getSerialNum())) {
                list = map.get(vo.getSerialNum());
            }
            list.add(vo);
            map.put(vo.getSerialNum(), list);

            if (StringUtils.isBlank(vo.getId())) {
                addMap.put(vo.getDeviceSubscriberNumber(), map);
            } else {
                newMap.put(vo.getId(), vo);
                updateMap.put(vo.getDeviceSubscriberNumber(), map);
                //更新同步至数据库
                ModeDevicePO po = new ModeDevicePO();
                BeanUtils.copyProperties(vo, po);
                po.preUpdate();
                modeDeviceDao.updateByPrimaryKeySelective(po);
            }
        }

        log.info(">>>>>>>>>>>添加："+addMap);
        log.info(">>>>>>>>>>>修改："+updateMap);
//        log.info(">>>>>>>>>>>删除："+oldDeviceList);

//        //删掉模式控制设备
//        for (ModeDeviceVO vo : oldDeviceList) {
//            if (!newMap.containsKey(vo.getId())) {
//                ModeDevicePO po = new ModeDevicePO();
//                po.setId(vo.getId());
//                po.preDelete();
//                modeDeviceDao.updateByPrimaryKeySelective(po);
//            }
//        }
//
//

        //查询所有已有的模式
        Example example = new Example(PlatformModePO.class);
        example.and().andEqualTo("modeId", modeSetVO.getId()).andEqualTo("delFlag", 0);
        List<PlatformModePO> list = platformModeDao.selectByExample(example);
        for (PlatformModePO platformModePO : list) {
            JSONArray cmds = new JSONArray();
            log.info(">>>>>>>>>>>>>>>>>>>>>>>>>>原来的模式");
            //删除下面的设备
            Example deple = new Example(ModeDevicePO.class);
            deple.and().andEqualTo("platformModeId", platformModePO.getId());
            modeDeviceDao.deleteByExample(deple);

            if (addMap.containsKey(platformModePO.getAccount())) {
                HashMap<String, List<ModeDeviceVO>> dmap = addMap.get(platformModePO.getAccount());
                Iterator<Map.Entry<String, List<ModeDeviceVO>>> it = dmap.entrySet().iterator();
                while (it.hasNext()) {
                    StringBuffer cmd = new StringBuffer();
                    Map.Entry<String, List<ModeDeviceVO>> entry = it.next();
                    List<ModeDeviceVO> lists = entry.getValue();
                    if(list==null||lists.size()==0){
                        continue;
                    }

                    for (ModeDeviceVO vo : lists) {
                        cmd.append(vo.getSerialNum()).append("_").append(vo.getProductCode()).append("_").append(vo.getCmdKey());
                        if (StringUtils.isNotBlank(vo.getCmdValue())) {
                            cmd.append("_").append(vo.getCmdValue());
                        }
                        cmds.add(cmd.toString());

                        ModeDevicePO po = new ModeDevicePO();
                        BeanUtils.copyProperties(vo, po);
                        po.preInsert();
                        po.setPlatformModeId(platformModePO.getId());
                        modeDeviceDao.insertSelective(po);
                    }
                }
                addMap.remove(platformModePO.getAccount());
            }
            if (updateMap.containsKey(platformModePO.getAccount())) {
                HashMap<String, List<ModeDeviceVO>> dmap = updateMap.get(platformModePO.getAccount());
                Iterator<Map.Entry<String, List<ModeDeviceVO>>> it = dmap.entrySet().iterator();
                while (it.hasNext()) {
                    StringBuffer cmd = new StringBuffer();
                    Map.Entry<String, List<ModeDeviceVO>> entry = it.next();
                    List<ModeDeviceVO> lists = entry.getValue();
                    if(list==null||lists.size()==0){
                        continue;
                    }
                    for (ModeDeviceVO vo : lists) {
                        cmd.append(vo.getSerialNum()).append("_").append(vo.getProductCode()).append("_").append(vo.getCmdKey());
                        if (StringUtils.isNotBlank(vo.getCmdValue())) {
                            cmd.append("_").append(vo.getCmdValue());
                         }
                        cmds.add(cmd.toString());
                        ModeDevicePO po = new ModeDevicePO();
                        BeanUtils.copyProperties(vo, po);
                        po.preInsert();
                        po.setPlatformModeId(platformModePO.getId());
                        modeDeviceDao.insertSelective(po);
                    }
                }
            }

            if (cmds == null||cmds.size()<1|| StringUtils.isBlank(cmds.toJSONString())) {
                //更新平台模式
                ModeApcosOpVO modeApcosOpVO = new ModeApcosOpVO();
                modeApcosOpVO.setId(platformModePO.getPlatformModeId());
                ApcosApiUtils.deletMode(platformModePO.getAccount(), modeApcosOpVO);
                platformModePO.preDelete();
                platformModeDao.updateByPrimaryKeySelective(platformModePO);
                continue;
            }
            if (!cmds.toJSONString().equals(platformModePO.getCmds())) {
                //更新本地数据
                platformModePO.preUpdate();
                platformModeDao.updateByPrimaryKeySelective(platformModePO);
                //更新平台模式
                ModeApcosSetVO modeApcosSetVO = new ModeApcosSetVO();
                modeApcosSetVO.setAccount(platformModePO.getAccount());
                modeApcosSetVO.setId(platformModePO.getPlatformModeId());
                modeApcosSetVO.setMode_name(platformModePO.getModeName());
                modeApcosSetVO.setMode_readme(platformModePO.getModeReadme());
                modeApcosSetVO.setEnable_mode(platformModePO.getEnableMode() == 1 ? "yes" : "no");
                modeApcosSetVO.setMode_exe_after_say(platformModePO.getModeExeAfterSay());
                modeApcosSetVO.setMode_exe_before_say(platformModePO.getModeExeBeforeSay());
                modeApcosSetVO.setMode_exe_say_sound(platformModePO.getModeExeSaySound());
                modeApcosSetVO.setMode_exe_say_speed(platformModePO.getModeExeSaySpeed());
                modeApcosSetVO.setMode_exe_say_voice(platformModePO.getModeExeSayVoice());
                ApcosApiUtils.updateMode(platformModePO.getAccount(), modeApcosSetVO, cmds.toJSONString());
            }
        }

        //剩余数据 需要添加模式
        Iterator<Map.Entry<String, HashMap<String, List<ModeDeviceVO>>>> it = addMap.entrySet().iterator();
        while (it.hasNext()) {
            Map.Entry<String, HashMap<String, List<ModeDeviceVO>>> entry = it.next();
            JSONArray cmds = new JSONArray();
            String  account=entry.getKey();

            Iterator<Map.Entry<String, List<ModeDeviceVO>>> mapList = entry.getValue().entrySet().iterator();
            while (mapList.hasNext()) {
                Map.Entry<String, List<ModeDeviceVO>> one = mapList.next();
                StringBuffer cmd=new StringBuffer();
                List<ModeDeviceVO> alist=one.getValue();
                for (ModeDeviceVO vo : alist) {
                    cmd.append(vo.getSerialNum()).append("_").append(vo.getProductCode()).append("_").append(vo.getCmdKey());
                    if (StringUtils.isNotBlank(vo.getCmdValue())) {
                        cmd.append("_").append(vo.getCmdValue());
                    }
                    cmds.add(cmd.toString());
                }
            }
            if (cmds != null) {
                //添加平台模式
                ModeApcosSetVO modeApcosSetVO = new ModeApcosSetVO();
                modeApcosSetVO.setMode_name(modePO.getModeName());
                modeApcosSetVO.setAccount(account);
                modeApcosSetVO.setMode_readme(modePO.getModeReadme());
                modeApcosSetVO.setEnable_mode(modePO.getEnableMode() == 1 ? "yes" : "no");
                modeApcosSetVO.setMode_exe_after_say(modePO.getModeExeAfterSay());
                modeApcosSetVO.setMode_exe_before_say(modePO.getModeExeBeforeSay());
                modeApcosSetVO.setMode_exe_say_sound(modePO.getModeExeSaySound());
                modeApcosSetVO.setMode_exe_say_speed(modePO.getModeExeSaySpeed());
                modeApcosSetVO.setMode_exe_say_voice(modePO.getModeExeSayVoice());
                String resultContent =ApcosApiUtils.addMode(account, modeApcosSetVO, cmds.toJSONString());
                JSONObject jsonObject= JSON.parseObject(resultContent);
                String modeId=(String) jsonObject.get("modeId");
                //添加本地模式记录
                PlatformModePO ppo=new PlatformModePO();
                ppo.setPlatformModeId(modeId);
                ppo.setAccount(account);
                ppo.setModeId(modePO.getId());
                ppo.setCmds(cmds.toString());
                BeanUtils.copyProperties(modePO, ppo);
                ppo.preInsert();
                platformModeDao.insertSelective(ppo);
                //添加本数据
                Iterator<Map.Entry<String, List<ModeDeviceVO>>> mapLists = entry.getValue().entrySet().iterator();
                while (mapLists.hasNext()) {
                    Map.Entry<String, List<ModeDeviceVO>> one = mapLists.next();
                    List<ModeDeviceVO> alist=one.getValue();
                    for (ModeDeviceVO vo : alist) {
                        ModeDevicePO po = new ModeDevicePO();
                        BeanUtils.copyProperties(vo, po);
                        po.preInsert();
                        po.setPlatformModeId(ppo.getId());
                        modeDeviceDao.insertSelective(po);
                    }
                }
                continue;
            }

        }

        log.info("===========设置模式添加结束===========");

    }

    @Override
    public void addMode(ModeAddSetVO modeAddVO) {
        //添加模式
        ModePO po = new ModePO();
        BeanUtils.copyProperties(modeAddVO, po);
        po.setEnableMode(1);
        if (po.getUser() != null) {
            po.setOrganizationId(po.getUser().getOrganizationId());
        }
        po.preInsert();
        int i = modeDao.insertSelective(po);
        if (i == Constants.SQL_RETUN_SUCCESS) {
            throw new BusinessException(Type.EXCEPTION_FAIL);
        }
        ModeSetVO modeSetVO=new ModeSetVO();
        modeSetVO.setId(po.getId());
        modeSetVO.setDeviceList(modeAddVO.getDeviceList());
        setMode(modeSetVO);
    }
}
